﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Helpers
{
    public class SimpleBezier
    {
        /// <summary>
        /// (1-t)*p0 + t * p1
        /// </summary>
        /// <param name="t"></param>
        /// <param name="p0"></param>
        /// <param name="p1"></param>
        /// <returns></returns>
        public static Vector3 Calc(float t,Vector3 p0,Vector3 p1){
            return (1 - t) * p0 + t * p1;
        }
        /// <summary>
        /// (1-t)方 * p0 + 2(1-t)*p1 + t方 * p2
        /// </summary>
        /// <param name="t"></param>
        /// <param name="p0"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        public static Vector3 Calc(float t, Vector3 p0, Vector3 p1, Vector3 p2)
        {
            float ft = 1 - t;
            float ftt = ft * ft;
            float tt = t * t;

            Vector3 b = ft * ft * p0 +
                2 * ft * t * p1 +
                tt * p2;
            return b;
        }
        /// <summary>
        /// (1-t)3次方 *ｐ0 + 3 * (1-t)方 * t * p1 + 3*(1-t)*t方*p1 + t3次方 * p3
        /// </summary>
        /// <param name="t"></param>
        /// <param name="p0"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <returns></returns>
        public static Vector3 Calc(float t, Vector3 p0, Vector3 p1, Vector3 p2,Vector3 p3)
        {
            float tt = t * t;
            float ttt = t * t * t;
            float ft = (1 - t);
            float ftt = ft * ft;
            float fttt = ft * ft * ft;

            Vector3 b = fttt * p0 +
                3 * ftt * t * p1 +
                3 * ft * tt * p2 +
                ttt * p3;
            return b;
        }
        /// <summary>
        /// 控制 一堆控制点,计算一条bezier路径.
        /// </summary>
        /// <param name="controlPoints"></param>
        /// <param name="segmentsPerCurve"></param>
        /// <returns></returns>
        public static List<Vector3> CalcPath(List<Vector3> controlPoints,int segmentsPerCurve)
        {
            List<Vector3> bizierPoints = new List<Vector3>();
            for (int i = 0; i < controlPoints.Count-3; i+=3)
            {
                Vector3 p0 = controlPoints[i];
                Vector3 p1 = controlPoints[i + 1];
                Vector3 p2 = controlPoints[i + 2];
                Vector3 p3 = controlPoints[i + 3];

                if (i == 0)
                {
                    bizierPoints.Add(Calc(0, p0, p1, p2, p3));
                }
                for (int j = 0; j < segmentsPerCurve; j++)
                {
                    float t = j / (float)segmentsPerCurve;
                    bizierPoints.Add(Calc(t, p0, p1, p2, p3));
                }
            }
            return bizierPoints;
        }
    }
}
